package com.zhihaoliang.coroutine.buss.excep.func

import com.zhihaoliang.coroutine.util.log
import kotlinx.coroutines.*

/**
 * @author 支豪亮
 * @date 2022/10/28 15:55
 * @des 取消异常
 */
object ExceptionCanceler {

    fun cancelExceptionNormal(mainScope:CoroutineScope) = mainScope.launch {
        val job = launch {
            val child = launch {
                try {
                    delay(Long.MAX_VALUE)
                } finally {
                    log("Child is cancelled")
                }
            }
            yield()
            log("Cancelling child")
            child.cancel()
            child.join()
            yield()
            log("Parent is not cancelled")
        }
        job.join()
    }

    @OptIn(DelicateCoroutinesApi::class)
    fun cancelExceptionHander(mainScope:CoroutineScope) = mainScope.launch {
        val handler = CoroutineExceptionHandler { _, exception ->
            log("CoroutineExceptionHandler got $exception")
        }
        val job = GlobalScope.launch(handler) {
            launch { // the first child
                try {
                    delay(Long.MAX_VALUE)
                } finally {
                    withContext(NonCancellable) {
                        log("Children are cancelled, but exception is not handled until all children terminate")
                        delay(100)
                        log("The first child finished its non cancellable block")
                    }
                }
            }
            launch { // the second child
                delay(10)
                log("Second child throws an exception")
                throw ArithmeticException()
            }
        }
        job.join()
    }
}